from django.utils.datastructures import SortedDict
from appengine_django import models
import re
import sets

def ceil(x):
	return int(round(x+.4999))

def filter(pred, lst):
	res=[]
	for itm in lst:
		if pred(itm):
			res.append(itm)
	return res

def update_existing(dict, src):
	for key in dict:
		if key in src:
			dict[key]=src[key]

def is_instance_of_any(object, classes):
	for cl in classes:
		if isinstance(object, cl):
			return True
	return False

camelcase_to_underscore = lambda str: re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', '_\\1', str).lower().strip('_')
camelcase_to_words = lambda str: camelcase_to_underscore(str).replace('_', ' ').capitalize() 


class SortedDictFromList(SortedDict):
    "A dictionary that keeps its keys in the order in which they're inserted."
    # This is different than django.utils.datastructures.SortedDict, because
    # this takes a list/tuple as the argument to __init__().
    def __init__(self, data=None):
        if data is None: data = []
        self.keyOrder = [d[0] for d in data]
        dict.__init__(self, dict(data))

    def copy(self):
        return SortedDictFromList([(k, copy.copy(v)) for k, v in self.items()])

class UniqueList(list):
	"List that cannot contain the same value multiple times."
	
	def __init__(self):
		self.key_set=sets.Set()
	
	def __contains__(self, item):
		if isinstance(item, models.BaseModel):
			key=str(item.key())
			return key in self.key_set
		return super(UniqueList, self).__contains__(item)
		
	
	def append(self, item):
		"""Appends value to list.
		
		If value is already present in the list, nothing is inserted."""

		if item not in self:
			if isinstance(item, models.BaseModel):
				self.key_set.add(str(item.key()))
			super(UniqueList, self).append(item)

	def extend(self, lst):
		"""Appends values from given list.
		
		If some value is already present in the list, it is not inserted."""
		for item in lst:
			self.append(item)

def human_trunc(value, maxsize, stopper='...'):
	stoplen = len(stopper)
	if len(value) > maxsize and maxsize > stoplen:
		return value[:(maxsize-stoplen)] + stopper
	else:
		return value[:maxsize]
	

def humanize_reference(target, context, model=None):
	from appengine_django import models
	if isinstance(target,  models.BaseModel):
		entity=target
		key=None
		capt=entity.get_caption()
	else:
		if not model:
			from gaev import exceptions
			raise exceptions.InsufficientArgumentsError()
		entity=None
		key=target
		capt=model.get_entity_caption(key)
	if context.use_html:
		from gaev.actions.url import get_action_url
		url=get_action_url('details', object=entity,  model=model,  key=key)
		return '<a href="%s">%s</a>' % (url, capt)
	else:
		return capt
